intel: Enable watchdog timer on Intel S10 platform
authorMuhammad Hadi Asyrafi Abdul Halim <[email protected]>
Tue, 19 Mar 2019 09:59:06 +0000 (17:59 +0800)
committerMuhammad Hadi Asyrafi Abdul Halim <[email protected]>
Thu, 21 Mar 2019 02:35:24 +0000 (10:35 +0800)
Watchdog driver support & enablement during platform setup

Signed-off-by: Muhammad Hadi Asyrafi Abdul Halim <[email protected]>
plat/intel/soc/stratix10/bl2_plat_setup.c
plat/intel/soc/stratix10/drivers/wdt/watchdog.c [new file with mode: 0644]
plat/intel/soc/stratix10/drivers/wdt/watchdog.h [new file with mode: 0644]
plat/intel/soc/stratix10/include/s10_clock_manager.h
plat/intel/soc/stratix10/platform.mk
plat/intel/soc/stratix10/soc/s10_clock_manager.c

index 9a2f9d3453d1ff433357d2cdfeafed7df7f2d685..58e8c029e0812e1d82169dbfa52f5e6a6b87a698 100644 (file)
@@ -32,6 +32,7 @@
 #include "aarch64/stratix10_private.h"
 #include "include/s10_mailbox.h"
 #include "drivers/qspi/cadence_qspi.h"
+#include "drivers/wdt/watchdog.h"
 
 
 const mmap_region_t plat_stratix10_mmap[] = {
@@ -72,6 +73,8 @@ void bl2_el3_early_platform_setup(u_register_t x0, u_register_t x1,
        deassert_peripheral_reset();
        config_hps_hs_before_warm_reset();
 
+       watchdog_init(get_wdt_clk(&reverse_handoff_ptr));
+
        console_16550_register(PLAT_UART0_BASE, PLAT_UART_CLOCK, PLAT_BAUDRATE,
                &console);
 
diff --git a/plat/intel/soc/stratix10/drivers/wdt/watchdog.c b/plat/intel/soc/stratix10/drivers/wdt/watchdog.c
new file mode 100644 (file)
index 0000000..b4dbe5f
--- /dev/null
@@ -0,0 +1,58 @@
+/*
+ * Copyright (c) 2019, Intel Corporation. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <common/debug.h>
+#include <lib/mmio.h>
+#include <platform_def.h>
+
+#include "watchdog.h"
+
+
+/* Reset watchdog timer */
+void watchdog_sw_rst(void)
+{
+       mmio_write_32(WDT_CRR, WDT_SW_RST);
+}
+
+/* Print component information */
+void watchdog_info(void)
+{
+       INFO("Component Type    : %x\r\n", mmio_read_32(WDT_COMP_VERSION));
+       INFO("Component Version : %x\r\n", mmio_read_32(WDT_COMP_TYPE));
+}
+
+/* Check watchdog current status */
+void watchdog_status(void)
+{
+       if (mmio_read_32(WDT_CR) & 1) {
+               INFO("Watchdog Timer in currently enabled\n");
+               INFO("Current Counter : 0x%x\r\n", mmio_read_32(WDT_CCVR));
+       } else {
+               INFO("Watchdog Timer in currently disabled\n");
+       }
+}
+
+/* Initialize & enable watchdog */
+void watchdog_init(int watchdog_clk)
+{
+       uint8_t cycles_i = 0;
+       uint32_t wdt_cycles = WDT_MIN_CYCLES;
+       uint32_t top_init_cycles = WDT_PERIOD * watchdog_clk;
+
+       while ((cycles_i < 15) && (wdt_cycles < top_init_cycles)) {
+               wdt_cycles = (wdt_cycles << 1);
+               cycles_i++;
+       }
+
+       mmio_write_32(WDT_TORR, (cycles_i << 4) | cycles_i);
+
+       watchdog_enable();
+}
+
+void watchdog_enable(void)
+{
+       mmio_write_32(WDT_CR, WDT_CR_RMOD|WDT_CR_EN);
+}
diff --git a/plat/intel/soc/stratix10/drivers/wdt/watchdog.h b/plat/intel/soc/stratix10/drivers/wdt/watchdog.h
new file mode 100644 (file)
index 0000000..e920236
--- /dev/null
@@ -0,0 +1,40 @@
+/*
+ * Copyright (c) 2019, Intel Corporation. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef __CAD_WATCHDOG_H__
+#define __CAD_WATCHDOG_H__
+
+#define WDT_BASE                       (0xFFD00200)
+#define WDT_REG_SIZE_OFFSET            (0x4)
+#define WDT_MIN_CYCLES                 (65536)
+#define WDT_PERIOD                     (20)
+
+#define WDT_CR                         (WDT_BASE + 0x0)
+#define WDT_TORR                       (WDT_BASE + 0x4)
+
+#define WDT_CRR                                (WDT_BASE + 0xC)
+
+#define WDT_CCVR                       (WDT_BASE + 0x8)
+#define WDT_STAT                       (WDT_BASE + 0x10)
+#define WDT_EOI                                (WDT_BASE + 0x14)
+
+#define WDT_COMP_PARAM_1               (WDT_BASE + 0xF4)
+#define WDT_COMP_VERSION               (WDT_BASE + 0xF8)
+#define WDT_COMP_TYPE                  (WDT_BASE + 0XFC)
+
+#define WDT_CR_RMOD                    (0x0)
+#define WDT_CR_EN                      (0x1)
+
+#define WDT_SW_RST                     (0x76)
+
+
+void watchdog_init(int watchdog_clk);
+void watchdog_enable(void);
+void watchdog_info(void);
+void watchdog_status(void);
+void watchdog_sw_rst(void);
+
+#endif
index 28192fa33e610e69e562bdb810d1bb3639abf1fc..99eb7a6c3d855a70c362914845d15581686009f0 100644 (file)
 #define ALT_CLKMGR_MAINPLL_VCOCALIB_HSCNT_SET(x) (((x) << 0) & 0x000000ff)
 #define ALT_CLKMGR_MAINPLL_VCOCALIB_MSCNT_SET(x) (((x) << 9) & 0x0001fe00)
 
+#define ALT_CLKMGR_MAINPLL_PLLGLOB_PSRC(x)     (((x) & 0x00030000) >> 16)
+#define ALT_CLKMGR_MAINPLL_PLLGLOB_PSRC_EOSC1  0x0
+#define ALT_CLKMGR_MAINPLL_PLLGLOB_PSRC_INTOSC 0x1
+#define ALT_CLKMGR_MAINPLL_PLLGLOB_PSRC_F2S    0x2
+
 #define ALT_CLKMGR_PERPLL                      0xffd100a4
 #define ALT_CLKMGR_PERPLL_EN                   0x0
 #define ALT_CLKMGR_PERPLL_BYPASS               0xc
 #define ALT_CLKMGR_PERPLL_VCOCALIB_MSCNT_SET(x) (((x) << 9) & 0x0001fe00)
 #define ALT_CLKMGR_PERPLL_VCOCALIB             0x58
 
+
+typedef struct {
+       uint32_t  clk_freq_of_eosc1;
+       uint32_t  clk_freq_of_f2h_free;
+       uint32_t  clk_freq_of_cb_intosc_ls;
+} CLOCK_SOURCE_CONFIG;
+
 void config_clkmgr_handoff(handoff *hoff_ptr);
+int get_wdt_clk(handoff *hoff_ptr);
 
 #endif
index 1f06fbdb45be183f40108325bd4c9c683855e675..fdd6e45b06c450e9903c7c5ced39a539ba809db5 100644 (file)
@@ -46,7 +46,8 @@ BL2_SOURCES     +=    \
                plat/intel/soc/stratix10/soc/s10_system_manager.c       \
                common/desc_image_load.c                                \
                plat/intel/soc/stratix10/soc/s10_mailbox.c              \
-               plat/intel/soc/stratix10/drivers/qspi/cadence_qspi.c
+               plat/intel/soc/stratix10/drivers/qspi/cadence_qspi.c    \
+               plat/intel/soc/stratix10/drivers/wdt/watchdog.c
 
 BL31_SOURCES   +=      drivers/arm/cci/cci.c                           \
                lib/cpus/aarch64/cortex_a53.S                           \
index 9d4617a037afa86c4ab27bba2dc851db4e09d9a1..dc90076ce36c0c7a05050c4640c490d636dbe3f4 100644 (file)
 #include "s10_clock_manager.h"
 #include "s10_handoff.h"
 
+static const CLOCK_SOURCE_CONFIG  clk_source = {
+       /* clk_freq_of_eosc1 */
+       (uint32_t) 25000000,
+       /* clk_freq_of_f2h_free */
+       (uint32_t) 460000000,
+       /* clk_freq_of_cb_intosc_ls */
+       (uint32_t) 50000000,
+};
 
 void wait_pll_lock(void)
 {
@@ -190,3 +198,37 @@ void config_clkmgr_handoff(handoff *hoff_ptr)
                        ALT_CLKMGR_INTRCLR_PERLOCKLOST_SET_MSK);
 }
 
+int get_wdt_clk(handoff *hoff_ptr)
+{
+       int main_noc_base_clk, l3_main_free_clk, l4_sys_free_clk;
+       int data32, mdiv, refclkdiv, ref_clk;
+
+       data32 = mmio_read_32(ALT_CLKMGR_MAINPLL + ALT_CLKMGR_MAINPLL_PLLGLOB);
+
+       switch (ALT_CLKMGR_MAINPLL_PLLGLOB_PSRC(data32)) {
+       case ALT_CLKMGR_MAINPLL_PLLGLOB_PSRC_EOSC1:
+               ref_clk = clk_source.clk_freq_of_eosc1;
+               break;
+       case ALT_CLKMGR_MAINPLL_PLLGLOB_PSRC_INTOSC:
+               ref_clk = clk_source.clk_freq_of_cb_intosc_ls;
+               break;
+       case ALT_CLKMGR_MAINPLL_PLLGLOB_PSRC_F2S:
+               ref_clk = clk_source.clk_freq_of_f2h_free;
+               break;
+       default:
+               ref_clk = 0;
+               assert(0);
+               break;
+       }
+
+       refclkdiv = ALT_CLKMGR_MAINPLL_PLLGLOB_REFCLKDIV(data32);
+       data32 = mmio_read_32(ALT_CLKMGR_MAINPLL + ALT_CLKMGR_MAINPLL_FDBCK);
+       mdiv = ALT_CLKMGR_MAINPLL_FDBCK_MDIV(data32);
+       ref_clk = (ref_clk / refclkdiv) * (6 + mdiv);
+
+       main_noc_base_clk = ref_clk / (hoff_ptr->main_pll_pllc1 & 0xff);
+       l3_main_free_clk = main_noc_base_clk / (hoff_ptr->main_pll_nocclk + 1);
+       l4_sys_free_clk = l3_main_free_clk / 4;
+
+       return l4_sys_free_clk;
+}